/* 读取配置项构造Handler */
const logger = require('./Logger')
const Handler = require('./Handler')
const WildcardMatcher = require('../src/WildcardMatcher')
const Executor = require('./Executor')

/* 后置项的内容会覆盖前置项 */
function HandlerBuilder (...configs) {
  try {
    const config = buildConfig(configs)
    return buildFromConfig(config)
  } catch (err) {
    if (err instanceof Executor.LoadingError) {
      return new ErrorHandler({ code: 'executor_loading_error', message: err.message })
    } else if (err instanceof Executor.NotFound) {
      return new ErrorHandler({ code: 'executor_not_found', message: err.message })
    } else {
      throw err
    }
  }
}

function buildConfig (configs) {
  configs = configs.filter(config => config)
  return Object.assign({}, ...configs)
}

function buildFromConfig (config) {
  const { token, event, branch, executor, command, stdout, stderr, cwd, user, group } = config
  let undefinedField = ['executor', 'command', 'cwd', 'user', 'group'].find(name => config[name] === undefined)
  if (undefinedField) {
    return new ErrorHandler({ code: 'config_error', message: `配置文件内缺少配置项${undefinedField}` })
  }
  return new Handler({
    token: token,
    eventMatcher: event ? new WildcardMatcher(event) : AlwaysTrueMatcher,
    branchMatcher: branch ? new WildcardMatcher(branch) : AlwaysTrueMatcher,
    executor: new Executor({ executor, command, stdout, stderr, cwd, user, group })
  })
}

class ErrorHandler {
  constructor (body) {
    this._body = body
  }

  match () {
    return true
  }

  handle () {
    return this._body
  }
}

const AlwaysTrueMatcher = {
  match: function () {
    return true
  }
}

HandlerBuilder._buildConfig = buildConfig

module.exports = HandlerBuilder
